<?php
/**
 * 
 * @author ferd
 *
 */
class Accounting {
	private static $_instance;
	
	private function __construct(){
		
	}
	
	public static function get_instance(){
		if(isset(self::$_instance)){
			self::$_instance = new Accounting();
		}
		return self::$_instance();
	}
	
	/**
	 * get all account types
	 * 
	 * @param boolean $enabled_only
	 */
	public static function get_account_types($enabled_only=TRUE){
		$ret = array();
		if(db_set_active(ACCTG_DB_NAME)){
			$sql = "select * from account_types";
			if($enabled_only){
				$sql .= " where enabled = 'Y'";
			}
			
			if($result = db_query($sql)){
				while($r = db_fetch_object($result)){
					$ret[] = $r;
				}
				$result->close();
			}
			
			db_set_active();
		} else {
			db_set_active();
			watchdog("accounting","Unable to connect to accounting database",
				array(),WATCHDOG_ERROR);
		}
		
		return $ret;
	}
	
	public static function add_account($title,$desc,$type_id,$parent=NULL){
		$ret = NULL;
		if(db_set_active(ACCTG_DB_NAME)){
			$sql = "insert into accounts (title,description,account_type_id,created) values ";
			$sql .= "('%s','%s',%d,sysdate())";
			if(db_query($sql,$title,$desc,$type_id) === FALSE){
				db_set_active();
				watchdog("accounting","Unable to add new account: %title %description %type_id",
					array("%title"=>$title,"%description"=>$desc,"%type_id"=>$type_id),
					WATCHDOG_ERROR);
			} else {
				$ret = db_last_insert_id("accounts","id");

				if(isset($parent)){
					self::set_parent_acct($ret,$parent);
				}
			}
			
			db_set_active();
		} else {
			db_set_active();
			watchdog("accounting","Unable to connect to accounting database.",
				array(),WATCHDOG_ERROR);
		}
		
		return $ret;
	}
	
	public static function set_parent_acct($account_id,$parent_id){
		if(db_set_active(ACCTG_DB_NAME)){
			$sql = "insert into account_hierarchy (parent_id,account_id) ";
			$sql .= "values (%d,%d)";
			if(db_query($sql,$parent_id,$account_id) === FALSE){
				db_set_active();
				watchdog("accounting","Unable to set as %parent_id as parent account of %child",
					array("%parent_id"=>$parent_id,"%child"=>$account_id),WATCHDOG_ERROR);
			}
			
			db_set_active();
		} else {
			db_set_active();
			watchdog("accounting","Unable to connect to accounting database.",
				array(),WATCHDOG_ERROR);
		}
	}
	
	/**
	 * get account by account id
	 * 
	 * @param unknown_type $account_id
	 */
	public static function get_account_by_id($account_id){
		$ret = NULL;
		if(db_set_active(ACCTG_DB_NAME)){
			$sql = "select * from accounts where id = %d";
			if(($result = db_query($sql,$account_id)) === FALSE){
				db_set_active();
				watchdog("accounting","Unable to retrieve accounts by id: %id",
					array("%id"=>$account_id),WATCHDOG_ERROR);
			} else {
				if($r = db_fetch_object($result)){
					$ret = $r;
				}
				$result->close();
			}
			
			db_set_active();
		} else {
			db_set_active();
			watchdog("accounting","Unable to connect to accounting database.",
				array(),WATCHDOG_ERROR);
		}
		return $ret;
	}
	
	/**
	 * get account by title
	 * 
	 * @param unknown_type $title
	 */
	public static function get_account_by_title($title){
		$ret = NULL;
		if(db_set_active(ACCTG_DB_NAME)){
			$sql = "select * from accounts where lower(title) = '%s'";
			if(($result = db_query($sql,strtolower($title))) === FALSE){
				if($r = db_fetch_object()){
					$ret = $r;
				}
				$result->close();
			} else {
				db_set_active();
				watchdog("accounting","Unable to retrieve account by title: %title",
					array("%title"=>$title));
			}
			
			db_set_active();
		} else {
			db_set_active();
			watchdog("accounting","Unable to connect to accounting database.",
				array(),WATCHDOG_ERROR);
		}
		return $ret;
	}
	
	public static function account_exists($title){
		if($title){
			return count(self::get_account_by_title($title)) == 1;
		} else {
			return FALSE;
		}
	}
	
	/**
	 * retrieves a list of accounts that match a given criteria
	 * 
	 * @param string $account
	 */
	public static function get_matching_accounts($title){
		$ret = array();
		if(db_set_active(ACCTG_DB_NAME)){
			$sql = "select * from accounts where lower(title) like '%s%' ";
			if(($result = db_query($sql,$title)) === FALSE){
				db_set_active();
				watchdog("accounting","Unable to retrieve matching accounts: %title.",
					array("%title"=>$title),WATCHDOG_ERROR);
			} else {
				while($r = db_fetch_object($result)){
					$ret[] = $r;
				}
				$result->close();
			}
			
			db_set_active();
		} else {
			db_set_active();
			watchdog("accounting","Unable to connect to accounting database.",
				array(),WATCHDOG_ERROR);
		}
		
		return $ret;
	}
	
	public static function get_matching_accounts_by_type($title,$type,$enabled_only=TRUE){
		$ret = array();
		if(db_set_active(ACCTG_DB_NAME)){
			$sql = "select * from accounts where type = %d and lower(title) like '%s%' ";
			if(($result = db_query($sql,$type,$title)) === FALSE){
				db_set_active();
				watchdog("accounting","Unable to retrieve matching accounts: %type %title.",
					array("%type"=>$type,"%title"=>$title),WATCHDOG_ERROR);
			} else {
				while($r = db_fetch_object($result)){
					$ret[] = $r;
				}
				$result->close();
			}
			
			db_set_active();
		} else {
			db_set_active();
			watchdog("accounting","Unable to connect to accounting database.",
				array(),WATCHDOG_ERROR);
		}
		
		return $ret;
	}
	
	public static function get_all_accounts(){
		$ret = array();
		if(db_set_active(ACCTG_DB_NAME)){
			$sql = "select * from accounts";
			if(($result = db_query($sql,$title)) === FALSE){
				db_set_active();
				watchdog("accounting","Unable to retrieve matching accounts: %title.",
					array("%title"=>$title),WATCHDOG_ERROR);
			} else {
				while($r = db_fetch_object($result)){
					$ret[] = $r;
				}
				$result->close();
			}
			
			db_set_active();
		} else {
			db_set_active();
			watchdog("accounting","Unable to connect to accounting database.",
				array(),WATCHDOG_ERROR);
		}
		
		return $ret;
	}
}